<!-- 文章详情 -->
<template>
    <div class="container" ref="containerRef">
        <!-- 文章目录 -->
        <ul class="catalogue" 
        v-if="screenType != 'small-screen' && 
        screenType != 'extraSmall-screen'">
            <li 
            class="catalogue-item"
            v-for="(item, index) in titleList" 
            :key="item.title"
            @click="anchorClick(item, index)"
            :class="currentIndex === index ? 'catalogue-active' : ''"
            :style="{ paddingLeft: `${5 + item.indent * 10}px` }">{{ item.title }}</li>
        </ul>
        <!-- 文章信息 -->
        <articleTitleCard :title="articleDetail.sortName+ ' | ' +articleDetail.articleTitle">
            <div class="info flx-align-center" :class="screenTypeClass.info">
                <!-- 作者 -->
                <ArticleAuthor :author="articleDetail.articleAuthor"></ArticleAuthor>
                <!-- 发布时间 -->
                <ArticleReleaseTime :createdAt="articleDetail.createdAt"></ArticleReleaseTime>
                <!-- 文章信息 -->
                <ArticleInfo 
                :viewsCount="articleDetail.viewsCount"
                :commentsCount="articleDetail.commentsCount"
                :like="articleDetail.likesCount"></ArticleInfo>
            </div>
            <div class="summary">{{ articleDetail.articleSummary }}</div>
        </articleTitleCard>
        <!-- 内容 -->
        <perview-markdown class="perview-markdown" ref="perviewRef" :text="articleDetail.articleContent"></perview-markdown>
        <!-- 标签 -->
        <div class="tags" :class="screenTypeClass.tags">
            <ArticleReleaseTime :createdAt="articleDetail.updatedAt" :timeText="'最后更新于：'"></ArticleReleaseTime>
            <ArticleTag :tags="articleDetail.tags" :isGoTagPage="false"></ArticleTag>
        </div>
        <!-- 作者版权 -->
        <div class="copyright">
            <div>作者：{{ articleDetail.articleAuthor }}</div>
            <div>版权声明：转载请注明文章出处</div>
        </div>
        <!-- 点赞 -->
        <Like 
        class="like" 
        :status="likeStatus" 
        @click="like"
        :text="likeText"></Like>
        <!-- 评论 -->
        <Comment 
        :commentTitle="'评论'" 
        :commentType="COMMENTS_TYPE.ARTICLE.value"
        :submitInfo="articleDetail"
        @commentSubmit="getArticleComments">
        </Comment>
        <!-- 评论列表 -->
        <CommentList
        :commentList="articleComments"
        :commentType="COMMENTS_TYPE.ARTICLE.value"
        @commentSubmit="getArticleComments" ></CommentList>
    </div>
</template>

<script setup>
import { nextTick, onMounted, onUnmounted, reactive } from 'vue';

import { useRoute } from 'vue-router';
import { useUserStore } from '@/store/system/user';
import { storeToRefs } from 'pinia';
import { websiteStore } from '@/store/system/website';
const { screenType } = storeToRefs(websiteStore());

import { goAnchor, trimSpaces } from '@/utils/tools-util';
import { articleApi } from '@/api/article/article-api';
import { commentApi } from '@/api/article/comment-api';
import { ElMessage } from 'element-plus';
import { COMMENTS_TYPE } from '@/constants/system/user-const';
import { articleStore } from '@/store/article/article';

import articleTitleCard from '@/components/article/article-title-card/article-title-card.vue';
import ArticleInfo from '@/components/article/article-info/article-info.vue';
import ArticleReleaseTime from '@/components/article/article-release-time/article-release-time.vue';
import ArticleAuthor from '@/components/article/article-author/article-author.vue';
import ArticleTag from '@/components/article/article-tag/article-tag.vue';
import Like from '@/components/animation/like/like.vue';
import Comment from '@/components/system/comment/comment.vue';
import CommentList from '@/components/system/comment-list/comment-list.vue';

// ========================= 实列挂载之前调用 =========================
// 数据初始化
onBeforeMount(() => {
    getArticleDetail();
    getArticleComments();
});

// ========================= 实例注销前 =========================
onUnmounted(() => {
    articleStore().setCurrentArticle({});
})

// ========================= 计算属性 =========================
const screenTypeClass = computed(() => {
    return {
        // [`info-${screenType.value}`]:true,
        // [`tags-${screenType.value}`]:true,
        info: `info-${screenType.value}`,
        tags: `tags-${screenType.value}`
    }
});

// ========================= 获取文章信息 =========================
const articleDetail = ref({});
const route = useRoute();
async function getArticleDetail() {
    if(!route.query.id) return;
    let params = {
        id: route.query.id
    };
    const res = await articleApi.findOne(params);
    articleDetail.value = res.data;
    fetchMarkdownTitles();
    setLikeStatus(res.data.users);
    articleStore().setCurrentArticle(res.data);
};

// 获取当前文章评论
const articleComments = ref([]);
async function getArticleComments() {
    console.log('111111111')
    if(!route.query.id) return;
    let conditions = {
        params: {
            articleId: route.query.id
        }
    }
    const res = await commentApi.list(conditions);
    articleComments.value = res.data.data;
};

// ========================= 设置文字目录 =========================
const perviewRef = ref(null);
const titleList = ref([]);      // 目录列表
const currentIndex = ref(0);    // 目录下标

async function getMarkdownTitles() {
    await nextTick();
    // 获取所有标题锚点
    const anchors = perviewRef.value.$el.querySelectorAll("h1,h2,h3,h4,h5,h6");
    // 将类数组(arguments对象) 转换为数组
    const titles = Array.from(anchors).filter((title) => !!title.innerText.trim());
    if (!titles.length) return [];
    const hTags = Array.from(new Set(titles.map((title) => title.tagName))).sort();
    return titles.map((el) => ({
        title: el.innerText,
        lineIndex: el.getAttribute("data-v-md-line"),
        indent: hTags.indexOf(el.tagName),
    }));
};

// 在需要的位置直接调用生成目录
const fetchMarkdownTitles = async () => {
    titleList.value = await getMarkdownTitles();
};

// ========================= 目录点击 =========================
const containerRef = ref();
async function anchorClick(item, index) {
    await nextTick();
    const heading = perviewRef.value.$el.querySelector(`[data-v-md-line="${item.lineIndex}"]`);
    goAnchor(heading, 0);
    // 更新currentIndex
    // currentIndex.value = index;
};

// ========================= 滚动 =========================
function handleScroll() {
    const headings = perviewRef.value.$el.querySelectorAll("h1,h2,h3,h4,h5,h6");
    // 当前在视图中的标题
    let currentHeading = null;
    for(let i = 0; i<headings.length; i++) {
        const heading = headings[i];
        const rect = heading.getBoundingClientRect();
        if (rect.top <= document.documentElement.clientHeight / 2 && rect.bottom >= 0) {
            currentHeading = heading;
            break;
        };
    };
    // 根据当前标题更新 currentIndex
    if (currentHeading) {
        const lineIndex = currentHeading.getAttribute("data-v-md-line");
        const index = titleList.value.findIndex((anchor) => anchor.lineIndex === lineIndex);
        if (index !== -1 && currentIndex.value !== index) {
            currentIndex.value = index;
        };
    };
};

// ========================= 实列挂载之后调用 =========================
onMounted(() => {
    window.addEventListener('scroll', handleScroll);
});
// ========================= 实列卸载后 =========================
onUnmounted(() => {
    window.removeEventListener('scroll', handleScroll);
});

// ========================= 文章点赞 =========================
const { id, token } = useUserStore();
let likeStatus = ref(false); // 当前文章是否被点赞
let likeText = ref('喜欢就点个赞吧！');
// 设置当前文章点赞状态
function setLikeStatus(data) {
    let obj = null;
    obj = data.find((item) => item.id === id );
    if(obj) {
        likeStatus.value = true;
        likeText.value = '已点赞！';
    }else {
        likeStatus.value = false;
        likeText.value = '喜欢就点个赞吧！';
    };
};
// 点赞 or 取消点赞
async function like() {
    try {
        if(!token) return ElMessage.error('请先登录！');
        let params = {
            userId: id,
            articleId: articleDetail.value.id
        };
        let res = null;
        likeStatus.value ? res = await articleApi.cancelLike(params) : 
        res = await articleApi.like(params);
        if(res.meta.status !== 200) throw new Error(res.meta.msg);
        likeStatus.value ? ElMessage.success('取消点赞成功') : ElMessage.success('点赞成功');
        getArticleDetail();
    } catch (e) {
        console.error(e);
        ElMessage.error(e.message);
    };
};
</script>

<style scoped lang="scss">
    @import '@/theme/public.scss';
    @import '@/theme/animations.scss';
    @import './article-details.scss';
</style>